package com.rightrule.rule.executor.rule;

import com.alibaba.fastjson.JSONObject;
import com.rightrule.rule.compile.CompilableInstance;
import com.rightrule.rule.constans.CommonConstant;
import com.rightrule.rule.executor.RuntimeContext;
import com.rightrule.rule.response.BaseExecutionResponse;
import groovy.lang.GroovyRuntimeException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.Map;

/**
 * groovy类型的规则
 */
@Data
@Slf4j
public class ScriptRule extends BaseRule {


    @Override
    BaseExecutionResponse executeAndGet(RuntimeContext context, Map<String, Object> varibleMap) {
        BaseExecutionResponse executionResponse = new BaseExecutionResponse();
        String exeResultData = "{}";
        // 如果有默认返回值，则先把默认返回值赋上
        if (!StringUtils.isEmpty(getDefaultResult())) {
            exeResultData = getDefaultResult();
        }

        try {
            CompilableInstance compilableInstance = getCompilableInstance();
            Map<String, Object> executeResult = (Map<String, Object>) compilableInstance.execute(varibleMap);
            // 如果执行后的结果为空,则返回空的map
            if (executeResult == null) {
                executeResult = Collections.EMPTY_MAP;

            } else {
                // 判断是否存在输出的变量里面包含了命中的规则标签，todo 调试的时候关注一下当前的数据结构
                if (executeResult.containsKey(CommonConstant.BKDECISION_RULE_IS_HIT)) {
                    // 设置规则是否命中
                    executionResponse.setIsHit((Boolean) executeResult.get(CommonConstant.BKDECISION_RULE_IS_HIT));
                    // 该标签不作为最终结果输出
                    executeResult.remove(CommonConstant.BKDECISION_RULE_IS_HIT);
                }
            }
            // 设置输出变量
            executionResponse.setOutput(executeResult);
        } catch (GroovyRuntimeException e) {
            log.error("run groovy error,errMsg = {},e = {},ruleId={},ruleName={}", e.getMessage(), e, getId(), getRuleName());
            executionResponse.setExecuteStaus(CommonConstant.EXECUTE_RULE_FAIL);
            // 出现异常后，将默认的返回值设置给输出变量
            executionResponse.setOutput(JSONObject.parseObject(exeResultData));
        } catch (Throwable e) {
            log.error("run groovy Throwable,errMsg = {},e = {},ruleId={},ruleName={}", e.getMessage(), e, getId(), getRuleName());
            executionResponse.setExecuteStaus(CommonConstant.EXECUTE_RULE_FAIL);
            // 出现异常后，将默认的返回值设置给输出变量
            executionResponse.setOutput(JSONObject.parseObject(exeResultData));
        }

        return executionResponse;
    }
}
